#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/filtering_stream.hpp>
using namespace boost::iostreams;
#include <fstream>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
int compress(const vector<char> &data, vector<char> &dest)
{
	assert(!data.empty());
	std::stringstream compressed;
	std::stringstream decompressed;
	decompressed.write(&data.at(0), data.size());
	boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
	out.push(boost::iostreams::zlib_compressor());
	out.push(decompressed);
	boost::iostreams::copy(out, compressed);
	compressed.seekg(0, ios::end);
	int length = compressed.tellg();
	dest.resize(length);
	compressed.seekg(0, ios::beg);
	dest.resize(length);
	compressed.read(&dest.at(0), length);
	return length;
}
int decompress(const vector<char> &data, vector<char> &dest)
{
	assert(!data.empty());
	std::stringstream compressed;
	std::stringstream decompressed;
	compressed.write(&data.at(0), data.size());
	boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
	out.push(boost::iostreams::zlib_decompressor());
	out.push(compressed);
	boost::iostreams::copy(out, decompressed);
	decompressed.seekg(0, ios::end);
	int length = decompressed.tellg();
	dest.resize(length);
	decompressed.seekg(0, ios::beg);
	assert(length > 0);
	decompressed.read(&dest.at(0), length);
	return length;
}
int main(int argc, char *argv[])
{
	if (argc < 3) {
		cout << "usage: hello src_file dest_file";
		return 0;
	}

	ifstream file(argv[1], ios_base::in | ios_base::binary);
	file.seekg(0, ios::end);
	int length = file.tellg();
	assert(length > 0);
	file.seekg(0, ios::beg);
	vector<char> data;
	data.resize(length);
	file.read(&data.at(0), length);
	vector<char> dest;
	cout << data.size() << " before compress" << endl;
	int size = compress(data, dest);
	std::cout << size << " after compress" << std::endl;
	ofstream out(argv[2], ios_base::out | ios_base::binary);
	out.write(&dest.at(0), dest.size());
	data.clear();
	std::cout << decompress(dest, data) << " after decompressed" << std::endl;
	return 0;
}

/*
#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>

int main() 
{
	using namespace std;
	using namespace boost::iostreams;
	
	ifstream file("hello.z", ios_base::in | ios_base::binary);
	filtering_streambuf<input> in;
	in.push(zlib_decompressor());
	in.push(file);
	boost::iostreams::copy(in, cout);
}
*/